# -*- coding: utf-8 -*-..,
##############################################################################
#
#    @author: PhongND
#    Copyright (C) 2014 Crea8s (http://www.crea8s.com) All Rights Reserved.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################


# -*- coding: UTF-8 -*-
'''
    magento

    :copyright: (c) 2014-2015 by PhongND
    :license: AGPLv3, see LICENSE for more details
'''
import magento
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp


class Invoice(osv.Model):
    """Invoice
    """
    _inherit = 'account.invoice'

    _columns = dict(
        crea8s_magento_id=fields.integer('Magento ID', readonly=True),
        crea8s_increment_id=fields.integer('Magento Increment ID', readonly=True),
        crea8s_magento_instance=fields.many2one(
            'crea8s.magento.instance', 'Magento Instance', readonly=True,
        ),
#         crea8s_magento_store_view=fields.many2one(
#             'crea8s.magento.store', 'Store', readonly=True,
#         ),
#         crea8s_magento_view=fields.many2one(
#             'crea8s.magento.view', 'View', readonly=True,
#         ),
    )
    
    _sql_constraints = [(
        'magento_id_instance_unique', 'unique(crea8s_magento_id, crea8s_magento_instance)',
        'A invoice must be unique in an instance' # PhongND
    )]
    
    
    def crea8s_find_or_create_using_magento_data(
        self, cursor, user, data_importing, context
    ):
        """
        Find or Create invoice using magento data

        :param cursor: Database cursor
        :param user: ID of current user
        :param data_importing: invoice Data from magento
        :param context: Application context
        :returns: Browse record of invoice invoice found/created
        """
        invoice = self.crea8s_find_using_magento_data(
            cursor, user, data_importing, context
        )
        
        if not invoice:
#             return False
            invoice = self.crea8s_create_using_magento_data(
                cursor, user, data_importing, context
            )
        else:
            invoice = self.crea8s_create_using_magento_data(
                cursor, user, data_importing, context, updateID = invoice.id
            )

        return invoice

    def crea8s_find_using_magento_data(
        self, cursor, user, data_importing, context
    ):
        """
        Create invoice using magento data
         
        :param cursor: Database cursor
        :param user: ID of current user
        :param data_importing: invoice Data from magento
        :param context: Application context
        :returns: Browse record of invoice invoice found
        """
        # each invoice has to be unique in an instance of magento
        invoice_ids = self.search(cursor, user, [
            ('crea8s_magento_id', '=', int(data_importing['invoice_id'])),
            ('crea8s_magento_instance', '=', context.get('magento_instance')),
        ], context=context)

        return invoice_ids and self.browse(
            cursor, user, invoice_ids[0], context
        ) or None

    def crea8s_create_using_magento_data(self, cursor, user, data_importing, context, updateID=None):
        """
        Create a invoice invoice from magento data
 
        :param cursor: Database cursor
        :param user: ID of current user
        :param data_importing: invoice Data from magento
        :param context: Application context
        :returns: Browse record of invoice invoice created
        """
        ormCurrency = self.pool.get('res.currency')
        ormInstance = self.pool.get('crea8s.magento.instance')
        ormStore = self.pool.get('crea8s.magento.store')
        ormView = self.pool.get('crea8s.magento.view')
        ormPartner = self.pool.get('res.partner')
        ormSaleOrder = self.pool.get('sale.order')
        ormSOlines = self.pool.get('account.invoice.line')
 
#         objStore = ormStore.browse(
#             cursor, user, context['magento_store'], context
#         )
#         objView = ormView.browse(
#             cursor, user, context['magento_view'], context
#         )
#         if not objView.store.shop:
#             raise osv.except_osv(
#                 _('Not Found!'),
#                 _(
#                     'Magento Store \'%s\' should have a shop configured.'
#                     % objView.store.name
#                 )
#             )
#         if not objView.store.shop.pricelist_id:
#             raise osv.except_osv(
#                 _('Not Found!'),
#                 _(
#                     'Shop on store \'%s\' does not have a pricelist!'
#                     % objView.store.name
#                 )
#             )
        
        #find instance
        objInstance = ormInstance.browse(
            cursor, user, context['magento_instance'], context
        )
        
        #find invoice
        arrSO_ids = ormSaleOrder.search(
            cursor, user, [('crea8s_magento_instance', '=', objInstance.id),
                           ('crea8s_magento_id', '=', data_importing['order_id']),
                           ], context=context
        )
        intSO_id = (len(arrSO_ids)>0) and arrSO_ids[0] or None
        objSO = ormSaleOrder.browse(
            cursor, user, 
            intSO_id, context)
        
        
        # find neu ko co SO, tao SO, roi tao invoice.
        # find partner
        # ??, AAAAA 
#         partner = objSO and objSO.partner_id or None
        
        
#         currencyid = None  # ??
#         currencyids = []
#         currencyids = ormCurrency.search(
#             cursor, user, [('name', 'ilike', data_importing['order_currency_code'])], context=context
#         ) # == ormCurrency.search_using_magento_code(
#         if len(currencyids) > 0:
#             currencyid = currencyids[0]

#         partner_invoice_address = \
#             ormPartner.crea8s_find_or_create_address_as_partner_using_magento_data(
#                 cursor, user, data_importing['billing_address'], partner, context
#             )
# 
#         partner_shipping_address = \
#             ormPartner.crea8s_find_or_create_address_as_partner_using_magento_data(
#                 cursor, user, data_importing['shipping_address'], partner, context
#             )
 
        #find journal ID
        journal_ids = self.pool.get('account.journal').search(cursor, user,
            [('type', '=', 'sale'), ('company_id', '=', objSO.company_id.id)],
            limit=1)
        if not journal_ids:
            raise osv.except_osv(_('Error!'),
                _('Please define sales journal for this company: "%s" (id:%d).') % (objSO.company_id.name, objSO.company_id.id)) 
        
            
            
        invoice_data = {
            'number': str(objInstance.order_prefix) + data_importing['increment_id'], # increment_id  
            'date_invoice': data_importing['created_at'],
            'origin': objSO and objSO.name or None,  # source document, okok
            'name': objSO and objSO.client_order_ref or None,
            'type': 'out_invoice',
            'reference': False,
            'order_id': objSO and objSO.id or None, #  
            'account_id': objSO and objSO.partner_id.property_account_receivable.id or None, # okok,?? maybe error:  a mandatory field is not correctly set 
            'partner_id':  objSO and objSO.partner_id.id or None, # ??, objSO.partner_invoice_id.id,
            'currency_id': objSO and objSO.pricelist_id.currency_id.id,
            'comment': '',
            #??, 'fiscal_position': sale.fiscal_position.id or sale.partner_id.property_account_position.id
            
            #magento identity.
            'journal_id': journal_ids and journal_ids[0] or None,
            'crea8s_magento_id': int(data_importing['invoice_id']),
            'crea8s_increment_id': int(data_importing['increment_id']),
            'crea8s_magento_instance': objInstance.id,
#             'crea8s_magento_view': objView.id,
#             'order_line': [],
            'invoice_line': self.crea8s_get_item_line_data_using_magento_data(
                cursor, user, data_importing, context
            )
        }
 
        if float(data_importing.get('shipping_amount')):
            print 'invoice.py: shipping_amount.....'
            invoice_data['invoice_line'].append(
                self.crea8s_get_shipping_line_data_using_magento_data(
                    cursor, user, data_importing, context
                )
            )
# #  
#         if float(data_importing.get('discount_amount')):
#             print 'invoice.py: discount_amount.....'
#             invoice_data['order_line'].append(
#                 self.crea8s_get_discount_line_data_using_magento_data(
#                     cursor, user, data_importing, context
#                 )
#             )
 
 
        
        invoice_id = None
        if updateID:
            # remove SO lines
            arrSOline_ids = ormSOlines.search(cursor, user, [('invoice_id', '=', updateID)], context=None)
            ormSOlines.unlink(cursor, user, arrSOline_ids, context=None)
            
            # update SO
            invoice_id = self.write(cursor, user, [updateID], invoice_data, context=context)
            invoice_id = updateID
        else:
            invoice_id = self.create(
                cursor, user, invoice_data, context=context
            )
        
#         # Process invoice now
#         self.process_invoice_using_magento_state(
#             cursor, user, invoice, data_importing['state'], context
#         )
#         
        invoice = self.browse(cursor, user, invoice_id, context)
        return invoice
    
    
    #?? discont...
#     def crea8s_get_discount_line_data_using_magento_data(self, cursor, user, data_importing, context):
#         """
#         Create a discount line for the given invoice using magento data
# 
#         :param cursor: Database cursor
#         :param user: ID of current user
#         :param data_importing: invoice Data from magento 
#         :param context: Application context
#         """
#     
#         ormWebsite = self.pool.get('crea8s.magento.website')
#         return (0, 0, {
#             'name': 'Magento Discount', # ....data_importing['discount_description'] or
#             'price_unit': float(data_importing.get('discount_amount', 0.00)),
#             'product_uom':
#                 ormWebsite.get_default_uom(
#                     cursor, user, context
#             ).id,
#             'magento_notes': data_importing.get('discount_description'),
#         }) # (0, 0, {})
    
    
    #?? shipping
    def crea8s_get_shipping_line_data_using_magento_data(self, cursor, user, data_importing, context):
 
        print 'invoice.py: crea8s_get_shipping_line_data_using_magento_data'
        ormWebsite = self.pool.get('crea8s.magento.website')
        ormProduct = self.pool.get('product.product')
         
#         taxes = self.crea8s_get_magento_shipping_tax(
#             cursor, user, data_importing, context
#         )
         
#         line_data = []
        values = {
            'name': 'Magento Shipping',
            'price_unit': float(data_importing.get('shipping_amount', 0.00)),
            'product_uom': ormWebsite.get_default_uom(
                    cursor, user, context
            ).id,  # context: magento_website ???
#             'product_uom_qty': float(item['qty_ordered']),
#             'magento_notes': ' - '.join([
#                 data_importing['shipping_method'],
#                 data_importing['shipping_description']
#             ]),
            'type': 'make_to_order',
#             'tax_id': [(6, 0, taxes)], #???
              
        }
 
        line_data = (0, 0, values) # ??, 0, 0, values   # okok
        return line_data

#         
        
    
    def crea8s_get_item_line_data_using_magento_data(self, cursor, user, data_importing, context):
        """
        Create a invoice invoice from magento data
 
        :param cursor: Database cursor
        :param user: ID of current user
        :param data_importing: invoice Data from magento
        :param context: Application context
        :returns: Browse record of invoice invoice created
        """
        
        ormWebsite = self.pool.get('crea8s.magento.website')
        ormProduct = self.pool.get('product.product')

        line_data = []
        for item in data_importing['items']:
#                 taxes = self.crea8s_get_magento_taxes(cursor, user, item, context)
                # If its a top level product, create it
                values = {
                    'name': item['name'],
                    'price_unit': float(item['price']),
                    'product_uom': ormWebsite.get_default_uom(
                            cursor, user, context
                    ).id,  # context: magento_website ???
                    'product_uom_qty': float(item['qty']),
#                     'magento_notes': item['product_options'],
                    'type': 'make_to_order',
#                     'tax_id': [(6, 0, taxes)], #???
                    'product_id':
                        ormProduct.crea8s_find_or_create_using_magento_id(
                            cursor, user, item['product_id'],
                            context=context
                    ).id
                }
                line_data.append((0, 0, values))

            #??? 


        return line_data
    
    
    #????????
#     def crea8s_get_magento_taxes(self, cursor, user, item_data, context):
#         """Match the tax in openerp with the tax rate from magento
#         Use this tax on invoice line
# 
#         :param cursor: Database cursor
#         :param user: ID of current user
#         :param item_data: Item Data from magento
#         :param context: Application context
#         """
#         ormTax = self.pool.get('account.tax')
# 
#         # Magento does not return the name of tax
#         # First try matching with the percent
#         tax_ids = ormTax.search(cursor, user, [
#             ('amount', '=', float(item_data['tax_percent']) / 100),
# #             ('crea8s_used_on_magento', '=', True) ,
#         ], context=context)
# 
#         # FIXME This will fail in the case of bundle products as tax comes
#         # comes with the children and not with parent
# 
#         return tax_ids
    
    
    #????????
#     def crea8s_get_magento_shipping_tax(self, cursor, user, data_importing, context):
#         """Match the tax in openerp which has been selected to be applied on
#         magento shipping.
# 
#         :param cursor: Database cursor
#         :param user: ID of current user
#         :param data_importing: invoice Data from magento
#         :param context: Application context
#         """
#         ormTax = self.pool.get('account.tax')
# 
#         # Magento does not return the name of tax or rate
#         # We can match only using the field set on tax in openerp itself
#         tax_ids = ormTax.search(cursor, user, [
# #             ('crea8s_apply_on_magento_shipping', '=', True),
# #             ('crea8s_used_on_magento', '=', True),
#         ], context=context)
# 
#         return tax_ids
    
    
    
    
    
    
    
    
    
    
    
    
